package hjw.com.controller;

import hjw.com.entity.*;
import hjw.com.service.*;
import hjw.com.util.JwtUtil;
import hjw.com.util.PackJsn;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

/**
 * <p>Project:Academic - PublicController
 *
 * @author IvanWei玮 -- maste
 * @version 1.0
 * @DataTime 2025/1/20 17:22
 * @since 1.8
 */
@RestController
@RequestMapping("/api/public")
public class PublicController {
    private final Logger logger = LoggerFactory.getLogger(PublicController.class);
    /**
     * 密码最小长度
     */
    private static final int MIN_PASSWORD_LENGTH = 6;
    /**
     * 密码最大长度
     */
    private static final int MAX_PASSWORD_LENGTH = 10;
    private final BookServiceImpl bookDao;
    private final LargeFileServiceImpl largeFileDao;
    private final TypeServiceImpl typeDao;
    private final HotServiceImpl hotDao;
    private final UserServiceImpl userDao;
    private final CommentServiceImpl commentDao;



    @Autowired
    public PublicController(BookServiceImpl bookDao, LargeFileServiceImpl largeFileDao, TypeServiceImpl typeDao, HotServiceImpl hotDao, UserServiceImpl userDao, CommentServiceImpl commentDao) {
        this.bookDao = bookDao;
        this.largeFileDao = largeFileDao;
        this.typeDao = typeDao;
        this.hotDao = hotDao;
        this.userDao = userDao;
        this.commentDao = commentDao;
    }

    @GetMapping("/comment/{bookid}")
    public String getComment(@PathVariable("bookid") String bookid){
        Map<String,Object> map = new HashMap<>();
        map.put("bookid", bookid);
        List<Comment> comments = commentDao.getComment(map);
        if(comments == null || comments.isEmpty()){
            return PackJsn.pack(200,"商品暂无评价");
        }
        return PackJsn.pack(200, "商品评价", comments);
    }

    @PostMapping("user/registration")
    public String register(@RequestParam Map<String, Object> map, @RequestParam(value = "mypic", required = false) MultipartFile myfile) {
        logger.info("用户注册");
        if (myfile == null || myfile.isEmpty()){
            return PackJsn.pack(203, "用户头像信息为空，注册失败");
        }
        if(map == null || map.isEmpty()){
            return PackJsn.pack(203, "用户信息为空，注册失败");
        }

        UUID picId = UUID.randomUUID();
        String newPicId = picId.toString().replace("-", "");
        LargeFile largeFile = null;
        try {
            largeFile = new LargeFile(newPicId, myfile.getOriginalFilename(), myfile.getBytes());
        } catch (IOException e) {
            return PackJsn.pack(203, "头像异常，请重新上传");
        }
        int add = largeFileDao.add(largeFile);
        if (add == 0){
            return PackJsn.pack(203, "头像上传失败");
        }
        logger.info("头像上传成功：" + largeFile);
        map.put("img", newPicId);
        map.put("role", "usr");
        map.put("closed", "000000");
        logger.info("注册：" + map);
        //密码加密交由服务去加密
        int registered = 0;
        try {
            registered = userDao.register(map);
        } catch (Exception e) {
            return PackJsn.pack(203, "账号已存在");
        }
        if (registered == 0){
            return PackJsn.pack(203, "用户注册失败");
        }
        return PackJsn.pack(200, "用户注册成功", map.get("id"));
    }

    @GetMapping("/showImg/{id}")
    public void showImg(@PathVariable("id")String pic, HttpServletResponse response) throws IOException {
        LargeFile one = largeFileDao.findOne(pic);
        if (one == null){
            logger.error("图片不存在");
            return;
        }
        byte[] bytes = (byte[]) one.getContent();
        OutputStream os = response.getOutputStream();
        response.setContentType("image/jpeg");
        os.write(bytes);
        //刷新资源
        os.flush();
    }

    @GetMapping("/getBook/{id}")
    public String getBook(@PathVariable("id")String id) {
        if (id == null){
            return PackJsn.pack(203, "商品id为空");
        }
        logger.info("获取商品信息");
        Book book = bookDao.findById(id);
        logger.info("book=" + book);
        if (book == null){
            logger.info("商品不存在");
            return PackJsn.pack(203, "商品不存在");
        }
        return PackJsn.pack(200, "商品信息", book);
    }

    @GetMapping("/getBookByItem")
    public String getBookByKey(@RequestParam Map<String, Object> map) {
        List<Book> findByKey = bookDao.findByParams(map);
        if (findByKey == null || findByKey.isEmpty()){
            return PackJsn.pack(203, "商品不存在");
        }
        logger.info("pageByKey=" + findByKey);
        return PackJsn.pack(200, "商品信息", findByKey);

    }

    @GetMapping("/getBooks")
    public String getBooks() {
        List<Book> books = bookDao.findAll();
        logger.info("books=" + books);
        return PackJsn.pack(200, "所有商品信息", books);
    }

    @PostMapping("/book/findPageByKey")
    public String getBook(@RequestBody Map<String, Object> map){
        logger.info("===>findPageByKey="+map);
        if(map.get("curPage") == null || map.get("lines") == null){
            return PackJsn.pack(203, "分页信息为空");
        }
        if (map.get("key") == null){
            return PackJsn.pack(203, "关键字为空");
        }
        Integer curPage = Integer.parseInt((String)map.get("curPage"));
        Integer lines = Integer.parseInt((String)map.get("lines"));
        curPage = (curPage - 1) * lines;
        map.put("curPage", curPage);
        map.put("lines", lines);
        //装配返回集合
        Map<String, Object> returnMap = new HashMap<>(2);
        int count = bookDao.findByTypeCount(map);
        returnMap.put("count", count);
        //控制数据库操作次数
        if (count == 0){
            //装配空值
            returnMap.put("books", "");
            return PackJsn.pack(200, "商品不存在",returnMap);
        }

        List<Book> bookList = bookDao.findPageByKey(map);
        logger.info("bookList=" + bookList);
        returnMap.put("books", bookList);

        logger.info("returnMap=" + returnMap);
        return PackJsn.pack(200, "商品信息", returnMap);

    }

    @GetMapping("/book/findPage/{curPage}/{lines}/{key}")
    public String getBookFindByPage(@PathVariable("curPage")Integer curPage, @PathVariable("lines")Integer lines, @PathVariable("key")Integer type ) {

        if(curPage == null || lines == null){
            return PackJsn.pack(203, "分页信息为空");
        }
        Map<String, Object> map = new HashMap<>(3);
        map.put("curPage", (curPage-1)*lines);
        map.put("lines", lines);
        if (type != null && type != 0) {
            map.put("type", type);
        }
        int count = 0;
        count = bookDao.findByTypeCount(map);


        if (count == 0){
            Map<String, Object> returnMap = new HashMap<>(2);
            returnMap.put("count", count);
            returnMap.put("books", null);
            return PackJsn.pack(200, "无商品信息",map);
        }
        //若该商品的总行数没有，则直接终止返回信息
        List<Book> books = bookDao.findByPage(map);

        logger.info("books=" + books);

        Map<String, Object> returnMap = new HashMap<>(2);
        returnMap.put("count", count);
        returnMap.put("books", books);
        return PackJsn.pack(200, "所有商品信息", returnMap);
    }

    @GetMapping("/getType")
    public String getType(){
        //一级类型
        List<Type> category = typeDao.findAllByCategory();
        //二级类型
        List<Type> types = typeDao.findAllByType();

        Set<Integer> set = new HashSet<>();
        //利用set去重，得到无重复的数组信息
        for (Type type : types) {
            set.add(type.getPid());
        }

        //得到所有二级类型的返回数组
        List<Object> list = new ArrayList<>();

        for (Integer integer : set) {
            List<Object> t = new ArrayList<>();
            //锁定数组的首位为本数组的pid
            t.add(integer);
            for (Type type : types) {
                if (type.getPid() == integer){
                    t.add(type);
                }
            }
            //不存在跳过
            if (t.isEmpty()){
                continue;
            }
            //存在存储信息
            list.add(t);
        }

        //获取数据交给js处理树状信息
        Map<String, Object> map = new HashMap<>(2);
        map.put("category", category);
        map.put("types", list);
        return PackJsn.pack(200, "商品类型信息", map);
    }

    @GetMapping("/getSalenum")
    public String getSalenum(){
        List<Book> books = bookDao.findBySalenum();
        for (Book book : books) {
            logger.info("月销量排行最佳的：" + book.getName());
        }
        return PackJsn.pack(200, "销量排行", books);
    }
    @GetMapping("/checkToken")
    public String checkToken(@RequestHeader(value = "Authorization", defaultValue = "") String token) {
        if (token == null || token.isEmpty()){
            return PackJsn.pack(000, "未登录", "");
        }
        //获取token体内容
        token = token.substring(7);
        logger.info("checkToken："+token);

        if (!JwtUtil.isValid(token)) {
            return PackJsn.pack(203, "登录过期，请重新登录", "");
        }

        String username = JwtUtil.getUsername(token);
        logger.info("TokenUid=" + username);
        if(username == null || username.isEmpty()){
            return PackJsn.pack(203, "请重新登录", "");
        }
        // Token 有效
        return PackJsn.pack(200, "token 有效", token);
    }

    @GetMapping("/getNewBooks")
    public String getNewBooks(){
        //表示为当页显示一行的个数 最小值为-1 暨数据为0条
        int row = 5;
        List<Book> books = bookDao.findByNews();
        //数据返回的数组
        List<List<Book>> list = new ArrayList<>();
        //用于数据组装拼接
        List<Book> b = new ArrayList<>(5);
        for (int i = 0; i < books.size(); i++) {
            b.add(books.get(i));
            if ((i+1) % row == 0){
                list.add(b);
                b = new ArrayList<>(5);
            }
        }

        for (Book book : books) {
            logger.info("最新上架的：" + book.getName());
        }
        return PackJsn.pack(200, "最新上架", list);
    }
    @GetMapping("/getHotBooks")
    public String getHotBooks(){
        //轮播图的信息
        Map<String, Object> map = new HashMap<>(1);
        map.put("type", 1);
        List<Hot> hots = hotDao.findByParam(map);

        //判断是否为空
        if (hots.isEmpty()){
            return PackJsn.pack(203, "无图书信息", null);
        }

        logger.info("hots" + hots);

        return PackJsn.pack(200, "热门商品信息", hots);
    }

}
